import { socket } from '@kit.NetworkKit'
import { TlsVersion } from '../TlsVersion';
import { SSLSocket } from './SSLSocket';
import { SSLSocketFactory } from './SSLSocketFactory';
import { NetAddress, ProxyOptions, TCPConnectOptions } from './TCPConnectOptions';

export class TLSSecureOptions implements  socket.TLSSecureOptions{
  /**
   * Certificate used to verify the identity of the server
   * @type {string | Array<string>}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Certificate used to verify the identity of the server.
   * @type {string | Array<string>}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  /**
   * Certificate used to verify the identity of the server, if it is not set, use system ca.
   * @type {?(string | Array<string>)}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 12
   */
  ca?: string | Array<string> = [];
  /**
   * Certificate proving the identity of the client
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Certificate proving the identity of the client
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  cert?: string = '';
  /**
   * Private key of client certificate
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Private key of client certificate
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  key?: string = '';
  /**
   * Password of the private key
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Password of the private key
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  password?: string = '';
  /**
   * TLS protocol version
   * @type {?Protocol | Array<Protocol>}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * TLS protocol version
   * @type {?(Protocol | Array<Protocol>)}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  protocols?: socket.Protocol | Array<socket.Protocol> = [socket.Protocol.TLSv12];
  /**
   * default is false, use local cipher.
   * @type {?boolean}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * default is false, use local cipher.
   * @type {?boolean}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  useRemoteCipherPrefer?: boolean = true;
  /**
   * <P>Supported signature algorithms. This string can contain summary algorithms(SHA256,MD5,etc),Public key algorithm(RSA-PSS,ECDSA,etc),
   * Combination of the two(For example 'RSA+SHA384') or TLS v1.3 Scheme name(For example  rsa_pss_pss_sha512)</P>
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * <P>Supported signature algorithms. This string can contain summary algorithms(SHA256,MD5,etc),Public key algorithm(RSA-PSS,ECDSA,etc),
   * Combination of the two(For example 'RSA+SHA384') or TLS v1.3 Scheme name(For example  rsa_pss_pss_sha512)</P>
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  signatureAlgorithms?: string = '';
  /**
   * Crypto suite specification
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Crypto suite specification
   * @type {?string}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  cipherSuite?: string = '';
  /**
   * Used to set up bidirectional authentication. The default value is false.
   * @type {?boolean}
   * @syscap SystemCapability.Communication.NetStack
   * @since 12
   */
  isBidirectionalAuthentication?: boolean = false;

  constructor(sslSocket: SSLSocket, sslSocketFactory: SSLSocketFactory) {
    // protocols cipherSuite来自于sslSocket
    let pls: Array<socket.Protocol> = []
    sslSocket.enabledProtocols.map((protocol) => {pls.push(TlsVersion.forNameWithProtocol(protocol))})
    this.protocols = pls
    // Android的逻辑是客户端发送所有支持的cipherSuite,服务器选择一个
    // Harmony的逻辑是客户端直接发送使用的cipherSuite
    // 当前暂时为"", 使用默认值
    this.cipherSuite = '' // sslSocket.enabledCipherSuites
    // ca cert key password 来自于sslSocketFactory
    this.cert = sslSocketFactory.cert ?? ''
    this.key = sslSocketFactory.key ?? ''
    this.ca = sslSocketFactory.ca ?? []
    this.password = sslSocketFactory.password ?? ''
    if (sslSocketFactory.cert && sslSocketFactory.key && sslSocketFactory.cert !== '' && sslSocketFactory.key !== ''){
      this.isBidirectionalAuthentication = true;
    }
  }
}

export class TLSConnectOptions implements socket.TLSConnectOptions{
  /**
   * Gateway address.
   * @type {NetAddress}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Gateway address.
   * @type {NetAddress}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  address: NetAddress;
  /**
   * Protocol http2TLS security related operations.
   * @type {TLSSecureOptions}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Protocol http2TLS security related operations.
   * @type {TLSSecureOptions}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  secureOptions: TLSSecureOptions;
  /**
   * Application layer protocol negotiation extension, such as "spdy/1", "http/1.1", "h2"
   * @type {?Array<string>}
   * @syscap SystemCapability.Communication.NetStack
   * @since 9
   */
  /**
   * Application layer protocol negotiation extension, such as "spdy/1", "http/1.1", "h2"
   * @type {?Array<string>}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 10
   */
  ALPNProtocols?: Array<string> = [];
  /**
   * Skip identity verification for remote servers. The default value is false.
   * @type {?boolean}
   * @syscap SystemCapability.Communication.NetStack
   * @since 12
   */
  skipRemoteValidation?: boolean = false;
  /**
   * Set this option for the proxy feature.
   * @type {?ProxyOptions}
   * @syscap SystemCapability.Communication.NetStack
   * @crossplatform
   * @since 18
   */
  proxy?: ProxyOptions;

  constructor(address: NetAddress, proxy: ProxyOptions, sslSocket: SSLSocket, sslSocketFactory: SSLSocketFactory) {
    this.address = address
    this.proxy = proxy
    this.secureOptions = new TLSSecureOptions(sslSocket, sslSocketFactory)
    this.skipRemoteValidation = sslSocketFactory.tm.skipRemoteValidation ?? false
  }
}

